package com.yami.shop.consign.common.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.vo.MarketAnalysisVO;
import com.yami.shop.bean.vo.UpDownVO;
import com.yami.shop.common.bean.PageDTO;
import com.yami.shop.common.bean.PageVO;
import com.yami.shop.common.util.PageUtil;
import com.yami.shop.consign.common.dao.ConsignAnalysisMapper;
import com.yami.shop.consign.common.dao.ConsignOptionalMapper;
import com.yami.shop.consign.common.dao.ConsignRecordMapper;
import com.yami.shop.consign.common.model.ConsignAnalysis;
import com.yami.shop.consign.common.model.ConsignOptional;
import com.yami.shop.consign.common.model.ConsignRecord;
import com.yami.shop.consign.common.service.ConsignAnalysisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ConsignAnalysisServiceImpl extends ServiceImpl<ConsignAnalysisMapper, ConsignAnalysis> implements ConsignAnalysisService {
    
    @Autowired
    private ConsignAnalysisMapper consignAnalysisMapper;

    @Autowired
    private ConsignOptionalMapper consignOptionalMapper;

    @Autowired
    private ConsignRecordMapper consignRecordMapper;

    @Override
    public void initialSave(Integer prodId) {
        ConsignAnalysis analysis = consignAnalysisMapper.getByProdId(prodId);
        if (Objects.isNull(analysis)) {
            ConsignAnalysis one = new ConsignAnalysis();
            one.setProdId(prodId);
            one.setHotspot(0);
            one.setLatestPrice(0);
            one.setIncrease(0.00);
            one.setClosingPrice(0);
            one.setDayHighPrice(0);
            one.setDayLowPrice(0);
            one.setWeekHighPrice(0);
            one.setWeekLowPrice(0);
            save(one);
        }
    }

    @Override
    public PageVO<MarketAnalysisVO> getPage(PageDTO pageDTO, Integer sort, Integer type, String userId, String prodName) {
        PageVO<MarketAnalysisVO> pageVO = PageUtil.doPage(pageDTO, () -> consignAnalysisMapper.getMarketList(sort, type, userId, prodName));
        return pageVO;
    }

    @Override
    public Map<String, Integer> upsDowns(String userId) {
        List<UpDownVO> upsDowns = consignAnalysisMapper.getUpsDowns(userId);
        Map<String, Integer> map = upsDowns.stream().collect(Collectors.toMap(UpDownVO::getType, UpDownVO::getNum));
        return map;
    }

    @Override
    public void update(Integer prodId) {
        ConsignAnalysis analysis = consignAnalysisMapper.getByProdId(prodId);
        
        //实时价/最新价
        ConsignRecord record = consignRecordMapper.selectOne(new LambdaQueryWrapper<ConsignRecord>()
                .eq(ConsignRecord::getProdId, prodId).eq(ConsignRecord::getType, 1).orderByDesc(ConsignRecord::getCreateTime).last("limit 1"));
        if (Objects.nonNull(record)) {
            analysis.setLatestPrice(record.getPrice().intValue());
        }
        
        //涨幅
        Double basics = Double.valueOf(analysis.getClosingPrice());
        Double recent = Double.valueOf(analysis.getLatestPrice());
        Double increase;
        if (basics == recent) {
            increase = 0.00;
        } else if (basics == 0 && recent != 0) {
            increase = 100.00;
        } else {
            increase = (recent - basics) / basics * 100;
        }
        analysis.setIncrease(increase);

        //今日
        Map<String, Long> dayMap = consignRecordMapper.todayExtremePrice(prodId);
        if (ObjectUtil.isNotEmpty(dayMap)) {
            analysis.setDayHighPrice(dayMap.get("high").intValue());
            analysis.setDayLowPrice(dayMap.get("low").intValue());
        }
        //本周
        Map<String, Long> weekMap = consignRecordMapper.weekExtremePrice(prodId);
        if (ObjectUtil.isNotEmpty(weekMap)) {
            analysis.setWeekHighPrice(weekMap.get("high").intValue());
            analysis.setWeekLowPrice(weekMap.get("low").intValue());
        }
        analysis.setUpdateTime(new Date());
        updateById(analysis);
    }

    @Override
    public void updateHotspot(Integer prodId) {
        ConsignAnalysis analysis = consignAnalysisMapper.getByProdId(prodId);
        Long hotspot = consignOptionalMapper.selectCount(new LambdaQueryWrapper<ConsignOptional>().eq(ConsignOptional::getProdId, prodId));
        analysis.setHotspot(hotspot.intValue());
        updateById(analysis);
    }

    @Override
    public void updateClosingPrice(Integer prodId) {
        ConsignRecord consignRecord = consignRecordMapper.closingPriceByProdId(prodId);
        if (Objects.nonNull(consignRecord)) {
            ConsignAnalysis analysis = consignAnalysisMapper.getByProdId(prodId);
            analysis.setClosingPrice(consignRecord.getPrice().intValue());
            updateById(analysis);
            update(analysis.getProdId());
        }
    }
    
    @Override
    public void updateBatchClosingPrice() {
        List<ConsignAnalysis> analyses = new ArrayList<>();
        List<ConsignAnalysis> list = consignAnalysisMapper.getList();
        list.stream().forEach(a -> {
            ConsignRecord record = consignRecordMapper.closingPriceByProdId(a.getProdId());
            if (Objects.nonNull(record)) {
                a.setClosingPrice(record.getPrice().intValue());
                analyses.add(a);
            }
        });
        if (CollUtil.isNotEmpty(analyses)) {
            updateBatchById(analyses);
            analyses.stream().forEach(a -> {
                update(a.getProdId());
            });
        }
    }
}
